<?php
/***********************************************************************
 * @package    	IvanEngine
 * @subpackage 	Core
 * @author     	Ivan <ivanzx@msn.com>
 * @created    	2010-05-20
 ***********************************************************************/
if(defined("IVANENGINE_CORE_VALIDATOR_MAPCOMPARE"))
	die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_VALIDATOR_MAPCOMPARE", true);

require_once (dirname(__FILE__).'/ValidatorMap.php');

class CValidatorMapCompare extends CValidatorMap
{
	const OP_EQUAL              = '==';
  	const OP_NOT_EQUAL          = '!=';
  	const OP_LESS_THAN          = '<';
  	const OP_LESS_THAN_EQUAL    = '<=';
  	const OP_GREATER_THAN       = '>';
  	const OP_GREATER_THAN_EQUAL = '>=';
  	
  	const NO_LeftField			= 'NO_LeftField';
  	const NO_Operator			= 'NO_Operator';
  	const NO_RightField			= 'NO_RightField';
  	const NO_ThrowGlobalError	= 'NO_ThrowGlobalError';
  	
 	public function __construct($leftField, $operator, $rightField, $options = array(), $messages = array())
  	{
	    $this->AddOption(self::NO_LeftField, $leftField);
	    $this->AddOption(self::NO_Operator, $operator);
	    $this->AddOption(self::NO_RightField, $rightField);
	    $this->AddOption(self::NO_ThrowGlobalError, false);
	
	    parent::__construct(null, $options, $messages);
  	}
  	
	protected function DoVerify($values)
	{
		if (is_null($values))
		{
		  	$values = array();
		}
	
		if (!is_array($values))
		{
		  	throw new CExceptionInvalidArgument('You must pass an array parameter to the clean() method');
		}
	
		$leftValue  = isset($values[$this->GetOption(self::NO_LeftField)]) ? $values[$this->GetOption(self::NO_LeftField)] : null;
		$rightValue = isset($values[$this->GetOption(self::NO_RightField)]) ? $values[$this->GetOption(self::NO_RightField)] : null;
	
		switch ($this->GetOption(self::NO_Operator))
		{
		  	case self::OP_GREATER_THAN:
				$valid = $leftValue > $rightValue;
				break;
		  	case self::OP_GREATER_THAN_EQUAL:
				$valid = $leftValue >= $rightValue;
				break;
		  	case self::OP_LESS_THAN:
				$valid = $leftValue < $rightValue;
				break;
		  	case self::OP_LESS_THAN_EQUAL:
				$valid = $leftValue <= $rightValue;
				break;
		  	case self::OP_NOT_EQUAL:
				$valid = $leftValue != $rightValue;
				break;
		  	case self::OP_EQUAL:
				$valid = $leftValue == $rightValue;
				break;
		  	default:
				throw new CExceptionInvalidArgument(sprintf('The operator "%s" does not exist.', $this->GetOption(self::NO_Operator)));
		}
	
		if (!$valid)
		{
		  	$error = new CExceptionValidator($this, self::NM_Invalid, array(
				self::NO_LeftField  => $leftValue,
				self::NO_RightField => $rightValue,
				self::NO_Operator   => $this->GetOption(self::NO_Operator),
		  	));
		  	if ($this->GetOption(self::NO_ThrowGlobalError))
		  	{
				throw $error;
		  	}
	
		  	throw new CExceptionValidatorMap($this, array($this->GetOption(self::NO_LeftField) => $error));
		}
	
		return $values;
	}

	public function AsString($indent = 0)
	{
		$options = $this->getOptionsWithoutDefaults();
		$messages = $this->getMessagesWithoutDefaults();
		unset($options[self::NO_LeftField], $options[self::NO_Operator], $options[self::NO_RightField]);
	
		$arguments = '';
		if ($options || $messages)
		{
		  $arguments = sprintf('(%s%s)',
			$options ? $options : ($messages ? '{}' : ''),
			$messages ? ', '.$messages : ''
		  );
		}
	
		return sprintf('%s%s %s%s %s',
		  str_repeat(' ', $indent),
		  $this->GetOption(self::NO_LeftField),
		  $this->GetOption(self::NO_Operator),
		  $arguments,
		  $this->GetOption(self::NO_RightField)
		);
	}
}

?>